/*
 * @Author: zhuxiaoyi
 * @Date: 2024-01-22 17:04:45
 * @LastEditor: zhuxiaoyi
 * @LastEditTime: 2024-12-18 15:25:29
 * @Description:
 */
import { Provide, Inject } from '@midwayjs/core';
import * as fs from 'fs';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { IAlgorithm, Ipage, algorithmFilter, AlgorithmType } from '../interface';
import { Algorithm } from '../entity/algorithm.entity';
import { AlgrithmType } from '../entity/algorithmType.entity';
import { Repository, Like, SelectQueryBuilder } from 'typeorm';
import { Context } from '@midwayjs/koa';
import { TaskService } from './task.service';
import { TaskDataResponseBody, ResponseBody, taskData } from '../types/ResponseBody'
import { CreateAlgorithmDto } from '../dto/AlgorithmDto';
@Provide()
export class AlgorithmService {
  @InjectEntityModel(Algorithm)
  AlgorithmModel: Repository<Algorithm>;

  @InjectEntityModel(AlgrithmType)
  AlgrithmTypeModel: Repository<AlgrithmType>;

  @Inject()
  ctx: Context;

  @Inject()
  taskService: TaskService;

  async createAlgorithm(file: any) {
    if (!file) {
      this.ctx.status = 415;
      this.ctx.body = {
        status: 'error',
        message: '文件为必填项',
      };
    }
    return await this.readJsonFileAndSave(file.data);
  }

  async readJsonFileAndSave(filePath: string) {
    try {
      // 读取文件内容
      const fileContent = fs.readFileSync(filePath, 'utf-8');

      // 尝试解析 JSON
      const jsonData = JSON.parse(fileContent);

      // 验证 JSON 结构
      if (this.validateJsonStructure(jsonData)) {
        // 将数据保存到数据库
        const algorithm = this.AlgorithmModel.create({
          name: jsonData.name,
          identifier: jsonData.identifier,
          description: jsonData.description,
          version: jsonData.version,
          application: jsonData.application,
          operating_system: jsonData.operating_system,
          executeType: jsonData.executeType ? jsonData.executeType : 1,
          parameters: JSON.stringify(jsonData.parameter), // 将参数数组转为字符串存储
        });

        await this.AlgorithmModel.save(algorithm);
        return { success: true, message: '数据保存成功' };
      } else {
        throw new Error('JSON 文件结构不符合预期');
      }
    } catch (error) {
      // 如果解析或保存失败，返回错误信息
      return {
        success: false,
        message: '处理 JSON 文件失败: ' + error.message,
      };
    }
  }

  /* async getAlgorithmList(params: algorithmFilter) {
    const [result, total] = await this.AlgorithmModel.findAndCount({
      where: { name: Like(`%${params.keyword ? params.keyword : ''}%`), type:params.type },
      skip: (params.page_index - 1) * params.page_size,
      take: params.page_size,
      order: { createDate: 'DESC' },
    });
    return {
      succes: true,
      data: result,
      total,
      message: '成功',
    };
  } */
  async getAlgorithmList(params: algorithmFilter) {
    const queryBuilder: SelectQueryBuilder<Algorithm> = this.AlgorithmModel.createQueryBuilder('algorithm');

    // 添加关键字搜索条件
    if (params.keyword) {
      queryBuilder.andWhere('algorithm.name LIKE :keyword', { keyword: `%${params.keyword}%` });
    }

    // 添加类型过滤条件
    if (params.type) {
      queryBuilder.andWhere(':type = ANY(algorithm.type)', { type: params.type });
    }

    // 添加分页和排序
    queryBuilder.skip((params.page_index - 1) * params.page_size)
      .take(params.page_size)
      .orderBy('algorithm.createDate', 'DESC');

    const [result, total] = await queryBuilder.getManyAndCount();
    return {
      success: true,
      data: await this.processTypeCN(result),
      total,
      message: '成功',
    };
  }

  async processTypeCN(result) {
    let progressResult = JSON.parse(JSON.stringify(result))
    if (progressResult.length > 0) for (const algorithm of progressResult) {
      algorithm.typeCN = [];
      if (algorithm.type && algorithm.type.length > 0) {
        const typePromises = algorithm.type.map(async (typeId) => {
          const algrithmType = await this.AlgrithmTypeModel.findOne({ where: { id: typeId } });
          if (algrithmType) {
            return algrithmType.name;
          }/* else{
            algorithm.type= algorithm.type.filter(item => item !== typeId);
            this.AlgorithmModel.save(algorithm)
          } */
        });
        const typeNames = await Promise.all(typePromises);
        algorithm.typeCN = typeNames;
      }
    }
    return progressResult

  }


  // 创建新的算法
  async createAlgorithm1(createAlgorithmDto: CreateAlgorithmDto) {
    const algorithm = this.AlgorithmModel.create(createAlgorithmDto);
    let result = await this.AlgorithmModel.save(algorithm);
    if (result) {
      return { success: true, message: '数据保存成功' };
    } else {
      return { success: false, message: '数据保存失败' };

    }
  }


  async deleteAlgorithm(id: number) {
    const algorithm = await this.AlgorithmModel.findOne({
      where: {
        id,
      },
    });
    if (!algorithm) {
      return {
        succes: false,
        message: '未查询到要删除的数据',
      };
    }

    // 删除单个
    let result = await this.AlgorithmModel.remove(algorithm);
    return {
      succes: true,
      data: result.identifier,
      message: '成功',
    };
  }


  async getAlgorithmById(id: number) {
    const algorithm = await this.AlgorithmModel.findOne({
      where: {
        id,
      },
    });
    if (!algorithm) {
      return {
        succes: false,
        message: '未查询到要删除的数据',
      };
    }
    return {
      succes: true,
      data: algorithm,
      message: '成功',
    };
  }

  async updateAlgorithm(updateDto: IAlgorithm, id: number) {
    const algorithm = await this.AlgorithmModel.findOne({
      where: { id },
    });

    if (!algorithm) {
      return {
        success: false,
        message: '未找到要更新的算法',
      };
    }
    // 更新算法信息
    Object.assign(algorithm, updateDto);
    const updatedAlgorithm = await this.AlgorithmModel.save(algorithm);

    return {
      success: true,
      data: updatedAlgorithm,
      message: '算法更新成功',
    };
  }

  async executeAlgorithm(id: number) {
    const algorithm = await this.AlgorithmModel.findOne({
      where: { id },
    });

    if (!algorithm) {
      return {
        success: false,
        message: '未找到要执行的算法',
      };
    }

    const task = await this.taskService.createTask(algorithm);
    if (!task) {
      return {
        success: false,
        message: '任务创建失败',
      };
    }

    return {
      success: true,
      data: {
        taskId: task.id,
      },
      message: '任务创建成功',
    };
  }


  async customAlgorithm(id: number, parameters: any): Promise<ResponseBody<taskData>> {
    const algorithm = await this.AlgorithmModel.findOne({
      where: { id },
    });

    if (!algorithm) {
      return {
        success: false,
        message: '未找到要执行的算法',
      };
    }

    // console.log(parameters)
    // console.log(algorithm.parameters)

    const parsedParameters = JSON.parse(algorithm.parameters);
    // 替换默认值
    parsedParameters.forEach(param => {
      const key = param.param_name;
      if (parameters.hasOwnProperty(key)) {
        param.default_value = parameters[key];
      }
    });
    algorithm.parameters = JSON.stringify(parsedParameters)
    console.log(algorithm.parameters);
    const task = await this.taskService.createTask(algorithm);
    if (!task) {
      return {
        success: false,
        message: '任务创建失败',
      };
    }

    return {
      success: true,
      data: {
        taskId: task.id,
      },
      message: '任务创建成功',
    };
  }


  async setTypeById(id: number, typeParams: AlgorithmType) {
    const algorithm = await this.AlgorithmModel.findOne({
      where: { id },
    });

    if (!algorithm) {
      return {
        success: false,
        message: '未找到要执行的算法',
      };
    }
    algorithm.type = typeParams.type
    this.AlgorithmModel.save(algorithm);
    return {
      success: true,
      data: algorithm,
      message: '类型更新成功',
    };
  }

  private validateJsonStructure(jsonData: any): boolean {
    // 验证 JSON 结构是否符合预期
    return (
      jsonData &&
      typeof jsonData === 'object' &&
      'name' in jsonData &&
      'identifier' in jsonData &&
      'description' in jsonData &&
      'version' in jsonData &&
      'application' in jsonData &&
      'operating_system' in jsonData &&
      'parameter' in jsonData &&
      Array.isArray(jsonData.parameter)
    );
  }
}
